//#define DEBUG
//Created by Roman Clarkson for Jaws.Core.Web
//Original work Copyright(C) 2008.  All Rights Reserved.

using System;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using Jaws.Core.Web.Entities;

namespace Jaws.Core.Web.Data
{
    public static class DataHelper
    {

        public static void SaveXmlData<T>(this XmlBusinessBase<T> xmlObjectToSave) where T : class, new()
        {
            var lockobject = new object();

            lock (lockobject)
            {
                var s = new XmlSerializer(typeof(T));


                TextWriter w = new StreamWriter(GetDataDirectoryAndFile(typeof(T), xmlObjectToSave.Id.ToString()));
                s.Serialize(w, xmlObjectToSave);
                w.Close();
            }
        }

        public static void SaveXmlData<T>(object xmlObjectToSave)
        {
            var lockobject = new object();

            lock (lockobject)
            {
                var s = new XmlSerializer(typeof(T));

                TextWriter w = new StreamWriter(typeof(T).Name);
                s.Serialize(w, xmlObjectToSave);
                w.Close();
            }
        }

        public static T GetXmlData<T>(Guid id)
        {
            var s = new XmlSerializer(typeof(T));
            TextReader r = new StreamReader(typeof(T).Name);
            var genericObject = (T)s.Deserialize(r);
            r.Close();
            return genericObject;
        }

        public static C GetXmlCollection<C, T>(this XmlCollectionBase<C, T> collectionBase)
            where C : XmlCollectionBase<C, T>, new()
            where T : XmlBusinessBase<T>, new()
        {
            var collection = new C();
            foreach (var file in Directory.GetFiles(GetDataDirectoryForXmlObject(typeof(T))))
            {
                var normalizedFileName = file;
                normalizedFileName = normalizedFileName.Remove(file.Length - 4, 4);
                normalizedFileName = normalizedFileName.Remove(0, normalizedFileName.LastIndexOf(@"\") + 1);
                var s = new XmlSerializer(typeof(T));
                TextReader r = new StreamReader(GetDataDirectoryAndFile(typeof(T), normalizedFileName));
                var genericObject = (T)s.Deserialize(r);
                r.Close();
                collection.Add(genericObject);
            }

            return collection;
        }

        public static void DeleteXmlData<T>(this XmlBusinessBase<T> xmlObjectToSave) where T : class, new()
        {
            var lockobject = new object();

            lock (lockobject)
            {
                File.Delete(GetDataDirectoryAndFile(typeof(T), xmlObjectToSave.Id.ToString()));
            }
        }

        private static string GetDataDirectoryAndFile(Type objectType, string id)
        {
            var xmlSubRootDirectory = string.Empty;
            foreach (Attribute attribute in objectType.GetCustomAttributes(false))
            {
                if (attribute.GetType().Name == "XmlDataDirectoryAttribute")
                {
                    xmlSubRootDirectory = ((XmlDataDirectoryAttribute)attribute).Root;
                    break;
                }
            }
//#if DEBUG
//            return string.Format(@"c:\app_data\{0}\{1}.xml", xmlSubRootDirectory, id);
//#endif

            CheckIfDirectoryExists(xmlSubRootDirectory);

            string fullpathandfile = string.Format(@"{0}\{1}\{2}.xml", AppDomain.CurrentDomain.GetData("DataDirectory"),
                                     xmlSubRootDirectory, id);

            return fullpathandfile;
        }

        private static void CheckIfDirectoryExists(string xmlSubRootDirectory)
        {
            string fullPath = string.Format(@"{0}\{1}\", AppDomain.CurrentDomain.GetData("DataDirectory"),
                                            xmlSubRootDirectory);

            if (!Directory.Exists(fullPath)) Directory.CreateDirectory(fullPath);
        }

        private static string GetDataDirectoryForXmlObject(ICustomAttributeProvider objectType)
        {
            var xmlSubRootDirectory = string.Empty;
            foreach (Attribute attribute in objectType.GetCustomAttributes(false))
            {
                if (attribute.GetType().Name == "XmlDataDirectoryAttribute")
                {
                    xmlSubRootDirectory = ((XmlDataDirectoryAttribute)attribute).Root;
                    break;
                }
            }
//#if DEBUG
//            return string.Format(@"c:\app_data\{0}", xmlSubRootDirectory);
//#endif
            
            string fullpath = string.Format(@"{0}\{1}\", AppDomain.CurrentDomain.GetData("DataDirectory"),
                                                   xmlSubRootDirectory);
            CheckIfDirectoryExists(xmlSubRootDirectory);
            return fullpath;
        }

    }
}